package need_learn.coding.ali;
/**
 * TODO 阿里， 一只青蛙一次可以跳上1级台阶，也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法（先后次序不同算不同的结果
 * 跳法数据特征
 * 1个台阶  1 1
 * 2个台阶  2 11 2
 * 3个台阶  3 111 12 21
 * 4个台阶  5 1111 112 121 22 211
 * 5个台阶  8 11111 1112  1211 1121 122  2111  221 212
 * 6个台阶  13 。。。
 * @author david
 * @version 1.0
 * @date 2021/4/20 14:56
 */
public class littleFog {
    public static void main(String[] args) {
        System.out.println(climbStairs(5));
        System.out.println(climbStairs3(5));
        System.out.println(climb(0, 5));
    }

    /**
     * 递归模拟爬楼梯在每层每次走一步或者两步的所有情况
     *
     * @param i：当前台阶数
     * @param n：总的台阶数
     * @return 总共有多少种走法
     */
    private static int climb(int i, int n) {
        //表示当前台阶数大于总台阶数，很显然这种情况不符合，走不通，记为 0
        if (i > n) {
            return 0;
        }
        //表示当前台阶数正好等于总的台阶数，那么这种情况符合，记为 1
        if (i == n) {
            return 1;
        }
        return climb(i + 1, n) + climb(i + 2, n);
    }


    //动态规划解法
    public static int climbStairs3(int n) {
        if (n == 1) {
            return 1;
        }
        //为什么n+1？ 需要确认
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }

    //斐波那契解法
    public static int climbStairs(int n) {
        if (n == 1) {
            return 1;
        }
        int first = 1;
        int second = 2;
        for (int i = 3; i <= n; i++) {
            int third = first + second;
            first = second;
            second = third;
        }
        return second;
    }
}
